package ntd.util;

import cn.hutool.core.lang.Opt;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjectUtil;
import ntd.util.fun.ComFun;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

public class ToolLockQueue {

    private static final ConcurrentHashMap<String, ConcurrentLinkedQueue<ComFun.Fun>> concurrentHashMap = new ConcurrentHashMap<>();

    private static synchronized ConcurrentLinkedQueue<ComFun.Fun> getQueue(String key) {
        ConcurrentLinkedQueue<ComFun.Fun> queue = concurrentHashMap.get(key);
        if (ObjectUtil.isNull(queue)) {
            concurrentHashMap.put(key, queue = new ConcurrentLinkedQueue<>());
            ConcurrentLinkedQueue<ComFun.Fun> finalQueue = queue;
            ThreadUtil.execAsync(() -> {
                while (true) {
                    Opt.ofNullable(finalQueue.poll()).ifPresent(UtilCatch::tryCatchNoRes);
                }
            });
        }
        return queue;
    }

    /**
     * 悲观锁运行
     * @param key
     * @param fun
     */
    public static void lockRun(String key, ComFun.Fun fun) {
        ConcurrentLinkedQueue<ComFun.Fun> queue = getQueue(key);
        queue.add(fun);
    }
}
